package com.lhkj.ct.meta.modules.gauge.common.enums;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.baomidou.mybatisplus.annotation.IEnum;
import com.lhkj.ct.base.exception.SystemException;
import com.lhkj.ct.base.utils.chart.JFreeChartConfig;
import com.lhkj.ct.base.utils.chart.JFreeChartUtil;
import com.lhkj.ct.meta.modules.psychology.model.entity.TblScaleReportContent;
import com.lhkj.ct.meta.modules.psychology.model.vo.PersonalReportInfo;
import lombok.Getter;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultKeyedValues2DDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 统计图表类型
 * </p>
 */
public enum ChartType implements IEnum<Integer> {

    HORIZONTAL_BAR(1, "横柱柱状图", (vo) -> {
        String seriesKey = vo.getScaleName();
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (TblScaleReportContent reportContent : vo.getDimReport()) {
            dataset.addValue(reportContent.getRealScore(), seriesKey, reportContent.getDimName());
        }
        // 100是给统计标题的
        int height = vo.getDimReport().size() * 40 + 100;
        JFreeChartConfig config = new JFreeChartConfig(vo.getScaleName(), null, "分数（分）", 600, height);
        return JFreeChartUtil.drawHorizontalBarChart(config, dataset);
    }),

    VERTICAL_BAR(2, "纵柱柱状图", (vo) -> {
        String seriesKey = vo.getScaleName();
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (TblScaleReportContent reportContent : vo.getDimReport()) {
            if (null == reportContent.getRealScore()) {
                continue;
            }
            dataset.addValue(reportContent.getRealScore(), seriesKey, reportContent.getDimName());

        }
        JFreeChartConfig config = new JFreeChartConfig(vo.getScaleName(), null, "分数（分）", 600, 350);
        return JFreeChartUtil.drawVerticalBarChart(config, dataset);
    }),

    HORIZONTAL_LINE(3, "横向折线图", (repVo) -> {
        String seriesKey = repVo.getScaleName();
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (TblScaleReportContent reportContent : repVo.getDimReport()) {
            if (null == reportContent.getRealScore()) {
                continue;
            }
            dataset.addValue(reportContent.getRealScore(), seriesKey, reportContent.getDimName());

        }
        JFreeChartConfig config = new JFreeChartConfig(repVo.getScaleName(), null, "分数（分）", 600, 500);
        return JFreeChartUtil.drawHorizontalLineChart(config, dataset);
    }),

    VERTICAL_LINE(4, "纵向折线图", (vo) -> {
        String seriesKey = vo.getScaleName();
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (TblScaleReportContent reportContent : vo.getDimReport()) {
            // fixme 折线图、症状自评量表(SCL-90)、青少年生活事件量表（ASLEC）、雷达图过滤掉总评
            if (Objects.equals(2, reportContent.getDimType())) {
                continue;
            }
            dataset.addValue(reportContent.getRealScore(), seriesKey, reportContent.getDimName());

        }
        int height = vo.getDimReport().size() > 4 ? vo.getDimReport().size() * 40 : 350;
        JFreeChartConfig config = new JFreeChartConfig(vo.getScaleName(), null, "分数（分）", 600, height);
        return JFreeChartUtil.drawVerticalLineChart(config, dataset);
    }),

    CARTEL(5, "卡特尔十六种人格因素测验（16PF）", (vo) -> {
        String seriesKey = vo.getScaleName();
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (TblScaleReportContent reportContent : vo.getDimReport()) {
            // fixme 卡特尔16PF
            if (reportContent.getDimName().contains("X") || reportContent.getDimName().contains("Y")) {
                continue;
            }
            if (null == reportContent.getRealScore()) {
                continue;
            }
            dataset.addValue(reportContent.getRealScore(), seriesKey, reportContent.getDimName());

        }
        int height = vo.getDimReport().size() > 4 ? vo.getDimReport().size() * 25 : 350;
        JFreeChartConfig config = new JFreeChartConfig(vo.getScaleName(), null, "分数（分）", 700, height);
        return JFreeChartUtil.cartelChart(config, dataset);
    }),

    CROSS(6, "十字坐标分布图", (vo) -> {
        throw new SystemException("为配置十字坐标分布图生成方式");
    }),

    SPIDER(7, "雷达分析图", (vo) -> {
        String seriesKey = vo.getScaleName();
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (TblScaleReportContent reportContent : vo.getDimReport()) {
            // fixme 雷达图过滤掉总评
            if (Objects.equals(2, reportContent.getDimType())) {
                continue;
            }
            if (null == reportContent.getRealScore()) {
                continue;
            }
            dataset.addValue(reportContent.getRealScore(), seriesKey, reportContent.getDimName());
        }
        JFreeChartConfig config = new JFreeChartConfig(vo.getScaleName(), null, "分数（分）", 500, 500);
        return JFreeChartUtil.drawSpiderChart(config, dataset);
    }),

    EPQ(8, "艾森克量表", (vo) -> {
        int height = vo.getDimReport().size() > 4 ? vo.getDimReport().size() * 40 : 350;
        JFreeChartConfig config = new JFreeChartConfig(vo.getScaleName(), null, "分数（分）", 600, height);
        Map<String, Double> epqMap = vo.getDimReport().stream().filter(f -> !Objects.equals(2, f.getDimType()))
                .collect(Collectors.toMap(TblScaleReportContent::getDimName, p -> p.getRealScore().doubleValue()));
        XYSeriesCollection epqDataset = new XYSeriesCollection();
        XYSeries series1 = new XYSeries(vo.getScaleName());
        series1.add(epqMap.getOrDefault("外倾性【E】", 0.0D), epqMap.getOrDefault("神经质【N】", 0.0D));
        epqDataset.addSeries(series1);
        return JFreeChartUtil.createEPQChart(config, epqDataset);

    }),

    MBTI(9, "MBTI人格特质量表", (vo) -> {
        JFreeChartConfig config = new JFreeChartConfig(vo.getScaleName(), null, "分数（分）", 600, 400);

        Map<String, Double> collect = vo.getDimReport().stream().filter(f -> !Objects.equals(2, f.getDimType()))
                .collect(Collectors.toMap(TblScaleReportContent::getDimName, p -> p.getRealScore().doubleValue()));
        DefaultKeyedValues2DDataset dataset1 = new DefaultKeyedValues2DDataset();
        int compare = NumberUtil.compare(collect.getOrDefault("外倾【E】", 0.0D), collect.getOrDefault("内倾【I】", 0.0D));
        double EI = compare > 0 ? -collect.getOrDefault("外倾【E】", 0.0D) : compare < 0 ? collect.getOrDefault("内倾【I】", 0.0D) : 0;
        int compare1 = NumberUtil.compare(collect.getOrDefault("感觉【S】", 0.0D), collect.getOrDefault("直觉【N】", 0.0D));
        double SN = compare1 > 0 ? -collect.getOrDefault("感觉【S】", 0.0D) : compare1 < 0 ? collect.getOrDefault("直觉【N】", 0.0D) : 0;
        int compare2 = NumberUtil.compare(collect.getOrDefault("思维【T】", 0.0D), collect.getOrDefault("情感【F】", 0.0D));
        double TF = compare2 > 0 ? -collect.getOrDefault("思维【T】", 0.0D) : compare2 < 0 ? collect.getOrDefault("情感【F】", 0.0D) : 0;
        int compare3 = NumberUtil.compare(collect.getOrDefault("判断【J】", 0.0D), collect.getOrDefault("知觉【P】", 0.0D));
        double JP = compare3 > 0 ? -collect.getOrDefault("判断【J】", 0.0D) : compare3 < 0 ? collect.getOrDefault("知觉【P】", 0.0D) : 0;
        dataset1.addValue(EI, "外倾(E)-内倾(I)", "外倾(E)");
        dataset1.addValue(SN, "感觉(S)-直觉(N)", "感觉(S)");
        dataset1.addValue(TF, "思考(T)-情感(F)", "思考(T)");
        dataset1.addValue(JP, "判断(J)-知觉(P)", "判断(J)");
        DefaultKeyedValues2DDataset dataset2 = new DefaultKeyedValues2DDataset();
        dataset2.addValue(EI, "外倾(E)-内倾(I)", "内倾(I)");
        dataset2.addValue(SN, "感觉(S)-直觉(N)", "直觉(N)");
        dataset2.addValue(TF, "思考(T)-情感(F)", "情感(F)");
        dataset2.addValue(JP, "判断(J)-知觉(P)", "知觉(P)");

        return JFreeChartUtil.createMBTIChart(config, dataset1, dataset2);


    }),

    MMPI(10, "明尼苏达多相个性测查表", (vo) -> {
        String seriesKey = vo.getScaleName();
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (TblScaleReportContent reportContent : vo.getDimReport()) {
            if (null == reportContent.getRealScore()) {
                continue;
            }
            dataset.addValue(reportContent.getRealScore(), seriesKey, reportContent.getDimName());
        }

        JFreeChartConfig config = new JFreeChartConfig(vo.getScaleName(), null, "分数（分）", 600, 500);

        return JFreeChartUtil.createMMPIChart(config, dataset);


    }),

    QTS(11, "QIUS在校学生气质量表", (vo) -> {
        JFreeChartConfig config = new JFreeChartConfig(vo.getScaleName(), null, "分数（分）", 600, 600);

        Map<String, Double> qtsMap = vo.getDimReport().stream()
                .filter(f -> !Objects.equals(2, f.getDimType()))
                .collect(Collectors.toMap(TblScaleReportContent::getDimName, p -> p.getRealScore().doubleValue()));
        XYSeriesCollection qtsDataset = new XYSeriesCollection();
        XYSeries qtsSeries = new XYSeries("总评");
        qtsSeries.add(qtsMap.getOrDefault("P维度", 0.0D), qtsMap.getOrDefault("B维度", 0.0D));
        qtsDataset.addSeries(qtsSeries);

        return JFreeChartUtil.createQTSChart(config, qtsDataset);


    }),

    SCL_90(12, "症状自评量表(SCL-90)", (vo) -> {
        String seriesKey = vo.getScaleName();
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (TblScaleReportContent reportContent : vo.getDimReport()) {
            // fixme 折线图、症状自评量表(SCL-90)、青少年生活事件量表（ASLEC）、雷达图过滤掉总评
            if (Objects.equals(2, reportContent.getDimType())) {
                continue;
            }
            if (null == reportContent.getRealScore()) {
                continue;
            }
            dataset.addValue(reportContent.getRealScore(), seriesKey, reportContent.getDimName());
        }

        JFreeChartConfig config = new JFreeChartConfig(vo.getScaleName(), "分数（分）", null, 600, 400);

        return JFreeChartUtil.drawVerticalLineChartWithMaker(config, dataset, 2.0);

    }),

    ASLEC(13, "青少年生活事件量表（ASLEC）", (vo) -> {
        String seriesKey = vo.getScaleName();
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (TblScaleReportContent reportContent : vo.getDimReport()) {
            // fixme 青少年生活事件量表（ASLEC）过滤掉总评
            if (Objects.equals(2, reportContent.getDimType())) {
                continue;
            }
            if (null == reportContent.getRealScore()) {
                continue;
            }
            dataset.addValue(reportContent.getRealScore(), seriesKey, reportContent.getDimName());

        }
        int height = vo.getDimReport().size() > 4 ? vo.getDimReport().size() * 40 : 350;
        JFreeChartConfig config = new JFreeChartConfig(vo.getScaleName(), null, "分数（分）", 600, height);
        return JFreeChartUtil.drawVerticalLineChartWithMaker(config, dataset, 2.0);

    }),

    MOCA(14, "蒙特利尔认知评估量表（MOCA）", (vo) -> {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (TblScaleReportContent reportContent : vo.getDimReport()) {
            // fixme 折线图、症状自评量表(SCL-90)、青少年生活事件量表（ASLEC）、雷达图过滤掉总评
            if (Objects.equals(2, reportContent.getDimType())) {
                continue;
            }
            if (null == reportContent.getRealScore()) {
                continue;
            }
            dataset.addValue(reportContent.getHighestScore(), "标准分", reportContent.getDimName());
            dataset.addValue(reportContent.getRealScore(), "测评分数", reportContent.getDimName());
        }

        JFreeChartConfig config = new JFreeChartConfig(vo.getScaleName(), null, "分数（分）", 450, 450);
        return JFreeChartUtil.drawSpiderChart(config, dataset);
    });

    @EnumValue
    private final int code;

    @Getter
    private final String desc;

    @Getter
    private Function<PersonalReportInfo, BufferedImage> buildChart;

    ChartType(int code, String desc, Function<PersonalReportInfo, BufferedImage> buildChart) {
        this.code = code;
        this.desc = desc;
        this.buildChart = buildChart;
    }


    @Override
    public Integer getValue() {
        return code;
    }

}
